package com.gewu.advertisement.core

import android.content.Context
import android.os.Build
import android.support.annotation.RequiresApi
import android.util.AttributeSet
import android.util.Log
import android.view.Gravity
import android.view.View
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.VideoView
import com.fasterxml.jackson.core.type.TypeReference
import com.gewu.advertisement.core.common.JacksonFactory
import com.gewu.advertisement.core.common.SupervisorLogScope
import com.gewu.advertisement.core.model.AdPlayState
import com.gewu.advertisement.core.model.Advertising
import com.gewu.advertisement.core.model.GewuPacket
import com.gewu.advertisement.core.model.PlayControl
import com.gewu.advertisement.core.service.AdvertisementService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch


/**
 * @author htt 2021/1/7
 */

@RequiresApi(Build.VERSION_CODES.O)
class AdvertisementView : FrameLayout, AdvertisementObserver {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    private var service: AdvertisementService? = null
    private val tag = "AdvertisementView"
    private val scope = SupervisorLogScope<AdvertisementView>(Dispatchers.Main)
    private val videoView: VideoView = VideoView(context)
    private val imageView: ImageView = ImageView(context)
    private val textLayout: FrameLayout = FrameLayout(context)
    private val webView: WebView = WebView(context)
    private val playListener = object : AdvertisementPlayer.VideoPlayListener {
        override fun start(advertising: Advertising) {
            val state =
                AdPlayState(
                    advertising.id,
                    AdPlayState.State.START,
                    System.currentTimeMillis() / 1000
                )
            service?.send(GewuPacket.AdPlayStateUpload(listOf(state)))
        }

        override fun complete(advertising: Advertising) {
            val state =
                AdPlayState(
                    advertising.id,
                    AdPlayState.State.STOP,
                    System.currentTimeMillis() / 1000
                )
            service?.send(GewuPacket.AdPlayStateUpload(listOf(state)))
        }
    }
    private val advertisementPlayer =
        AdvertisementPlayer(context, videoView, imageView, webView, textLayout, playListener)

    init {
        val videoLayoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        videoLayoutParams.gravity = Gravity.CENTER
        addView(videoView, videoLayoutParams)
        val imageLayoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        imageLayoutParams.gravity = Gravity.CENTER
        addView(imageView, imageLayoutParams)
        val textLayoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        addView(textLayout, textLayoutParams)
        val webViewLayoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        addView(webView, webViewLayoutParams)
        webView.setWebViewClient(WebViewClient())
        this.visibility = View.GONE
    }

    /**
     * 更新广告列表
     */
    override fun updateAdvertisements(advertisements: List<Advertising>, adTypes: Array<out Advertising.Type>, newAdList: Boolean) {
        scope.launch {
            val sp  = context.getSharedPreferences("Screen", Context.MODE_PRIVATE)
            var sharedPreferencesKey = "videoAdListStr"
            if(Advertising.Type.TEXT in adTypes){
                sharedPreferencesKey = "textAdListStr"
            }
            if(newAdList){
                //来自平台下发新的广告列表，更新存储的播放列表
                val adStr = JacksonFactory.objectMapper.writeValueAsString(advertisements)
                sp.edit().putString(sharedPreferencesKey, adStr).apply()
                //没有广告就隐藏控件
                Log.i(tag, "播放下发的广告列表")
                val adList = advertisements.filter { it.adType in adTypes }
                this@AdvertisementView.visibility = if(adList.isEmpty()) View.GONE else View.VISIBLE
                advertisementPlayer.submitMedia(adList)
            }else{
                if(advertisements.isEmpty()){
                    var adStr = sp.getString(sharedPreferencesKey, null)
                    if(!adStr.isNullOrEmpty()){
                        val advertisingList: List<Advertising> = JacksonFactory.objectMapper.readValue(
                            adStr,
                            object : TypeReference<List<Advertising?>?>() {})
                        Log.i(tag, "播放历史保存的广告列表")
                        //没有广告就隐藏控件
                        val adList = advertisingList.filter { it.adType in adTypes }
                        this@AdvertisementView.visibility = if(adList.isEmpty()) View.GONE else View.VISIBLE
                        advertisementPlayer.submitMedia(adList)
                        return@launch
                    }
                }else{
                    val adStr = JacksonFactory.objectMapper.writeValueAsString(advertisements)
                    sp.edit().putString(sharedPreferencesKey, adStr).apply()
                }
                val adList = advertisements.filter { it.adType in adTypes }
                this@AdvertisementView.visibility = if(adList.isEmpty()) View.GONE else View.VISIBLE
                advertisementPlayer.submitMedia(adList)
            }
        }
    }


    override fun playControl(playControl: PlayControl) {
        scope.launch {
            advertisementPlayer.playControl(playControl)
        }
    }

    override fun setAdvertisementService(service: AdvertisementService?) {
        this.service = service
    }

    override fun toString(): String {
        return "AdvertisementView(${hashCode()})"
    }
}